x86: Fix circular page reference destruction in relinquish_memory().
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 28 Oct 2008 11:25:20 +0000 (11:25 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 28 Oct 2008 11:25:20 +0000 (11:25 +0000)
Tested by Jan Beulich and fixes a memory leak, but there is more to be
done here.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/domain.c
xen/arch/x86/mm.c

index 30f03c99acf94caab98341806602cc81d56f0893..0c39db4718ac0b26057dc636607f6d2e9734b6d2 100644 (file)
@@ -1687,7 +1687,6 @@ static int relinquish_memory(
             {
                 if ( free_page_type(page, x, 0) != 0 )
                     BUG();
-                put_page(page);
                 break;
             }
         }
index b2a9c3a0851de85c31e2f49135f433f8a1f32a78..fdd70d2dd929e8d8d0dbb3c68ae0d2992d37e874 100644 (file)
@@ -1973,6 +1973,7 @@ int free_page_type(struct page_info *page, unsigned long type,
         page->nr_validated_ptes = 1U << PAGETABLE_ORDER;
         page->partial_pte = 0;
     }
+
     switch ( type & PGT_type_mask )
     {
     case PGT_l1_page_table:
@@ -1998,6 +1999,15 @@ int free_page_type(struct page_info *page, unsigned long type,
         BUG();
     }
 
+    return rc;
+}
+
+
+static int __put_final_page_type(
+    struct page_info *page, unsigned long type, int preemptible)
+{
+    int rc = free_page_type(page, type, preemptible);
+
     /* No need for atomic update of type_info here: noone else updates it. */
     if ( rc == 0 )
     {
@@ -2062,7 +2072,7 @@ static int __put_page_type(struct page_info *page,
                                            x, nx)) != x) )
                     continue;
                 /* We cleared the 'valid bit' so we do the clean up. */
-                return free_page_type(page, x, preemptible);
+                return __put_final_page_type(page, x, preemptible);
             }
 
             /*